from typing import Dict, List, Optional, Any
from langchain_core.prompts import ChatPromptTemplate
from langchain_ollama import ChatOllama
from langchain.schema import BaseMessage, HumanMessage, AIMessage
# 移除已弃用的ConversationBufferMemory导入
import json
import re
import traceback
from datetime import datetime, timedelta
import sys
import os
from loguru import logger

# 配置loguru日志
logger.remove()  # 移除默认配置

# 控制台日志 - 显示INFO及以上级别
logger.add(
    sys.stdout,
    level="INFO",
    format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
    colorize=True
)

# 文件日志 - 详细日志，包含DEBUG级别
logger.add(
    "logs/flood_forecast_parameter_collector.log",
    level="DEBUG",
    format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} | {process.id} | {thread.id} - {message}",
    rotation="10 MB",
    retention="7 days",
    compression="zip",
    encoding="utf-8"
)

# 错误日志单独文件
logger.add(
    "logs/flood_forecast_parameter_collector_error.log",
    level="ERROR",
    format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} | {process.id} | {thread.id} - {message}\n{exception}",
    rotation="5 MB",
    retention="30 days",
    compression="zip",
    encoding="utf-8"
)

# 导入配置
try:
    import sys
    import os
    # 添加项目根目录到Python路径
    current_dir = os.path.dirname(os.path.abspath(__file__))
    parent_dir = os.path.dirname(current_dir)
    if parent_dir not in sys.path:
        sys.path.append(parent_dir)
    
    from config.config import OLLAMA_CONFIG
except ImportError:
    # 如果无法导入配置，使用默认配置
    OLLAMA_CONFIG = {
        "base_url": "http://localhost:11434",
        "chat_model": "qwen:latest"
    }
    logger.warning("无法导入配置文件，使用默认配置")


class FloodForecastParameterCollector:
    """洪水预报参数收集器
    
    通过对话式交互收集洪水预报所需的完整参数信息
    """
    
    def __init__(self):
        self.llm = ChatOllama(
            base_url=OLLAMA_CONFIG["base_url"],
            model=OLLAMA_CONFIG["chat_model"],
            temperature=0.1
        )
        # 使用简单的消息列表替代已弃用的ConversationBufferMemory
        self.chat_history = []
        self.required_parameters = {
            "reservoir_name": {"required": True, "description": "水库名称", "value": None},
            "forecast_model": {"required": True, "description": "预报模型类型", "value": None},
            "start_time": {"required": True, "description": "预报开始时间", "value": None},
            "forecast_duration": {"required": True, "description": "预报时长(小时)", "value": None},
            "rainfall_forecast_period": {"required": True, "description": "降雨预见期(小时)", "value": None},
            "target_variable": {"required": True, "description": "预测目标变量", "value": None}
        }
        self.conversation_state = "collecting"  # collecting, validating, awaiting_confirmation, completed, error
        self.validation_errors = {}  # 存储验证错误信息
        self.pending_confirmation = False  # 是否等待用户确认
        
    def _create_system_prompt(self) -> str:
        """动态创建系统提示词"""
        missing_params = [k for k, v in self.required_parameters.items() if v["value"] is None]
        collected_params = {k: v["value"] for k, v in self.required_parameters.items() if v["value"] is not None}
        
        # 安全地序列化已收集的参数
        try:
            collected_params_str = json.dumps(collected_params, ensure_ascii=False, indent=2) if collected_params else "{}"
        except Exception as e:
            collected_params_str = str(collected_params)
            
        # 安全地获取缺失参数描述
        try:
            missing_descriptions = [self.required_parameters[p]["description"] for p in missing_params]
        except Exception as e:
            missing_descriptions = missing_params
        
        return f"""
你是一个专业的洪水预报参数收集助手。你的任务是通过对话收集用户进行洪水预报所需的完整参数信息。

当前已收集的参数：
{collected_params_str}

还需要收集的参数：
{missing_descriptions}

参数说明：
- reservoir_name: 水库名称（如：大伙房水库、三峡水库等）
- forecast_model: 预报模型类型（如：新安江模型、萨克拉门托模型等）
- start_time: 预报开始时间（格式：YYYY-MM-DD HH:MM）
- forecast_duration: 预报时长，单位小时（如：24、48、72等）
- rainfall_forecast_period: 降雨预见期，单位小时（如：6、12、24等）
- target_variable: 预测目标变量（如：流量、水位、库容等）

请根据用户的回答，智能提取参数信息，并针对缺失的关键参数进行友好的反问。
如果用户提供的信息不够具体或有歧义，请要求澄清。
当所有必需参数都收集完成后，请总结所有参数并询问用户确认。

回答格式要求：
1. 如果还有参数需要收集，请自然地询问缺失的参数
2. 如果所有参数已收集完成，请总结所有参数并询问用户确认
3. 保持对话自然、专业、友好
4. 不要在回复中包含任何特殊标记或格式化字符串
"""

    def _extract_parameters_from_text(self, text: str) -> Dict[str, Any]:
        """从文本中提取参数"""
        logger.debug(f"开始从文本提取参数: {text}")
        extracted = {}
        text_lower = text.lower()
        
        try:
            # 提取水库名称
            logger.debug("开始提取水库名称")
            reservoir_patterns = [
                r'([\u4e00-\u9fa5]{2,}水库)',  # 至少两个汉字+水库
                r'([\u4e00-\u9fa5]{2,}库)',   # 至少两个汉字+库
                r'(三峡|大伙房|丹江口|小浪底)',  # 特定水库名称
            ]
            for i, pattern in enumerate(reservoir_patterns):
                try:
                    logger.debug(f"尝试水库模式 {i+1}: {pattern}")
                    match = re.search(pattern, text)
                    if match:
                        logger.debug(f"匹配成功: {match}")
                        groups = match.groups()
                        logger.debug(f"匹配组: {groups}, 组数量: {len(groups)}")
                        if groups and len(groups) > 0:
                            reservoir_name = match.group(1)
                            extracted['reservoir_name'] = reservoir_name
                            logger.debug(f"提取到水库名称: {reservoir_name}")
                            break
                except (IndexError, AttributeError) as e:
                    logger.error(f"水库名称提取错误: {e}, 模式: {pattern}")
                    continue
                    
            # 提取预报模型
            logger.debug("开始提取预报模型")
            model_patterns = [r'(新安江)', r'(萨克拉门托)', r'(tank)', r'(api)', r'(sma)']
            for i, pattern in enumerate(model_patterns):
                try:
                    logger.debug(f"尝试模型模式 {i+1}: {pattern}")
                    match = re.search(pattern, text_lower)
                    if match:
                        logger.debug(f"模型匹配成功: {match}")
                        groups = match.groups()
                        logger.debug(f"模型匹配组: {groups}, 组数量: {len(groups)}")
                        if groups and len(groups) > 0:
                            extracted['forecast_model'] = match.group(1)
                            logger.debug(f"提取到预报模型: {match.group(1)}")
                            break
                except (IndexError, AttributeError) as e:
                    logger.error(f"预报模型提取错误: {e}, 模式: {pattern}")
                    continue
                    
            # 提取目标变量
            logger.debug("开始提取目标变量")
            target_patterns = [r'(流量)', r'(水位)', r'(库容)', r'(入库流量)', r'(出库流量)']
            for i, pattern in enumerate(target_patterns):
                try:
                    logger.debug(f"尝试目标变量模式 {i+1}: {pattern}")
                    match = re.search(pattern, text)
                    if match:
                        logger.debug(f"目标变量匹配成功: {match}")
                        groups = match.groups()
                        logger.debug(f"目标变量匹配组: {groups}, 组数量: {len(groups)}")
                        if groups and len(groups) > 0:
                            extracted['target_variable'] = match.group(1)
                            logger.debug(f"提取到目标变量: {match.group(1)}")
                            break
                except (IndexError, AttributeError) as e:
                    logger.error(f"目标变量提取错误: {e}, 模式: {pattern}")
                    continue
                
            # 提取时间信息
            logger.debug("开始提取时间信息")
            time_patterns = [
                r'(\d{4}-\d{1,2}-\d{1,2}\s+\d{1,2}:\d{1,2})',
                r'(\d{4}年\d{1,2}月\d{1,2}日\s*\d{1,2}时)',
                r'(\d{4}/\d{1,2}/\d{1,2}\s+\d{1,2}:\d{1,2})',
                r'(\d{1,2}-\d{1,2}\s+\d{1,2}:\d{1,2})',
                r'(\d{1,2}/\d{1,2}\s+\d{1,2}:\d{1,2})',
                r'(\d{1,2}月\d{1,2}日\s*\d{1,2}时)',
                r'(\d{1,2}月\d{1,2}日\s*\d{1,2}点)',
                r'(明天|后天|今天)\s*(上午|下午|早上|晚上)?\s*(\d{1,2})[时点]',
                r'(明天|后天|今天)',
                r'(\d{1,2}月\d{1,2}日)',
                r'从\s*(\d{4}-\d{1,2}-\d{1,2}\s+\d{1,2}:\d{1,2})\s*开始',
                r'开始时间[：:]?\s*(\d{4}-\d{1,2}-\d{1,2}\s+\d{1,2}:\d{1,2})',
                r'预报开始[：:]?\s*(\d{4}-\d{1,2}-\d{1,2}\s+\d{1,2}:\d{1,2})'
            ]
            for i, pattern in enumerate(time_patterns):
                try:
                    logger.debug(f"尝试时间模式 {i+1}: {pattern}")
                    match = re.search(pattern, text)
                    if match:
                        logger.debug(f"时间匹配成功: {match}")
                        groups = match.groups()
                        logger.debug(f"时间匹配组: {groups}, 组数量: {len(groups)}")
                        if groups and len(groups) > 0:
                            # 对于多个捕获组的情况，选择最完整的时间信息
                            if len(groups) == 1:
                                extracted['start_time'] = match.group(1)
                            elif len(groups) >= 3 and '明天|后天|今天' in pattern:
                                # 处理相对时间表达式
                                relative_day = match.group(1)
                                time_period = match.group(2) if match.group(2) else ''
                                hour = match.group(3) if match.group(3) else '8'
                                extracted['start_time'] = f"{relative_day} {time_period} {hour}时"
                            else:
                                # 选择第一个非空的捕获组
                                for group in groups:
                                    if group and group.strip():
                                        extracted['start_time'] = group
                                        break
                            logger.debug(f"提取到开始时间: {extracted.get('start_time')}")
                            break
                except (IndexError, AttributeError) as e:
                    logger.error(f"时间提取错误: {e}, 模式: {pattern}")
                    continue
                    
            # 提取预报时长
            logger.debug("开始提取预报时长")
            duration_patterns = [
                r'预报\s*(\d+)\s*小时',
                r'预报\s*(\d+)\s*天', 
                r'时长\s*(\d+)\s*小时',
                r'(\d+)\s*小时.*预报',
                r'(\d+)\s*h',
                r'(\d+)\s*天'
            ]
            # 如果没有明确的预报时长关键词，检查是否为简单的数字+时间单位
            duration_extracted = False
            for i, pattern in enumerate(duration_patterns):
                try:
                    logger.debug(f"尝试时长模式 {i+1}: {pattern}")
                    match = re.search(pattern, text_lower)
                    if match:
                        logger.debug(f"时长匹配成功: {match}")
                        groups = match.groups()
                        logger.debug(f"时长匹配组: {groups}, 组数量: {len(groups)}")
                        if groups and len(groups) > 0:
                            duration = int(match.group(1))
                            full_match = match.group(0)
                            logger.debug(f"完整匹配: {full_match}")
                            if '天' in full_match:
                                duration *= 24
                                logger.debug(f"转换为小时: {duration}")
                            extracted['forecast_duration'] = duration
                            logger.debug(f"提取到预报时长: {duration}")
                            duration_extracted = True
                            break
                except (IndexError, AttributeError, ValueError) as e:
                    logger.error(f"预报时长提取错误: {e}, 模式: {pattern}")
                    continue
            
            # 如果预报时长没有提取到，尝试简单的数字+时间单位模式
            if not duration_extracted:
                simple_duration_patterns = [r'^\s*(\d+)\s*小时\s*$', r'^\s*(\d+)\s*天\s*$', r'^\s*(\d+)\s*h\s*$']
                for pattern in simple_duration_patterns:
                    simple_match = re.search(pattern, text.strip(), re.IGNORECASE)
                    if simple_match:
                        duration = int(simple_match.group(1))
                        if '天' in pattern or 'day' in pattern.lower():
                            duration *= 24
                        extracted['forecast_duration'] = duration
                        logger.debug(f"提取到预报时长（简单模式）: {duration}小时")
                        break
                    
            # 提取降雨预见期
            logger.debug("开始提取降雨预见期")
            rainfall_patterns = [
                r'预见期\s*(\d+)\s*小时', 
                r'降雨\s*(\d+)\s*小时',
                r'降雨预见期\s*(\d+)\s*小时',
                r'(\d+)\s*小时.*预见期',
                r'预见期.*(\d+)\s*小时'
            ]
            # 如果上述模式都没匹配到，且文本中只包含数字+小时的简单格式，也尝试提取
            if not any(re.search(pattern, text) for pattern in rainfall_patterns):
                simple_hour_pattern = r'^\s*(\d+)\s*小时\s*$'
                simple_match = re.search(simple_hour_pattern, text.strip())
                if simple_match:
                    logger.debug(f"使用简单小时模式匹配: {simple_match}")
                    extracted['rainfall_forecast_period'] = int(simple_match.group(1))
                    logger.debug(f"提取到降雨预见期（简单模式）: {simple_match.group(1)}")
            for i, pattern in enumerate(rainfall_patterns):
                try:
                    logger.debug(f"尝试降雨预见期模式 {i+1}: {pattern}")
                    match = re.search(pattern, text)
                    if match:
                        logger.debug(f"降雨预见期匹配成功: {match}")
                        groups = match.groups()
                        logger.debug(f"降雨预见期匹配组: {groups}, 组数量: {len(groups)}")
                        if groups and len(groups) > 0:
                            extracted['rainfall_forecast_period'] = int(match.group(1))
                            logger.debug(f"提取到降雨预见期: {match.group(1)}")
                            break
                except (IndexError, AttributeError, ValueError) as e:
                    logger.error(f"降雨预见期提取错误: {e}, 模式: {pattern}")
                    continue
                    
        except Exception as e:
            # 如果整个提取过程出错，记录错误但不中断程序
            logger.error(f"参数提取过程中出现错误: {e}")
            logger.error(f"错误详情: {traceback.format_exc()}")
            logger.error(f"输入文本: {text}")
                
        logger.debug(f"最终提取结果: {extracted}")
        return extracted

    def _update_parameters(self, extracted_params: Dict[str, Any]):
        """更新参数值"""
        for key, value in extracted_params.items():
            if key in self.required_parameters and value is not None:
                self.required_parameters[key]["value"] = value
                logger.info(f"参数已更新: {key} = {value}")
                
    def _validate_parameter_format(self, param_name: str, value: Any) -> Dict[str, Any]:
        """验证参数格式并提供修正建议
        
        Returns:
            Dict包含:
            - is_valid: 是否有效
            - corrected_value: 修正后的值（如果可以修正）
            - error_message: 错误信息
            - suggestion: 修正建议
        """
        result = {
            "is_valid": True,
            "corrected_value": value,
            "error_message": "",
            "suggestion": ""
        }
        
        try:
            if param_name == "reservoir_name":
                # 水库名称验证
                if not isinstance(value, str) or len(value.strip()) < 2:
                    result["is_valid"] = False
                    result["error_message"] = "水库名称格式不正确"
                    result["suggestion"] = "请提供完整的水库名称，如：大伙房水库、三峡水库等"
                else:
                    result["corrected_value"] = value.strip()
                    
            elif param_name == "forecast_model":
                # 预报模型验证
                valid_models = ["新安江", "新安江模型", "萨克拉门托", "萨克拉门托模型", "tank", "tank模型", "api", "api模型"]
                if not any(model in str(value).lower() for model in [m.lower() for m in valid_models]):
                    result["is_valid"] = False
                    result["error_message"] = "预报模型格式不正确"
                    result["suggestion"] = "请选择有效的预报模型：新安江模型、萨克拉门托模型、Tank模型、API模型等"
                    
            elif param_name == "target_variable":
                # 目标变量验证
                valid_variables = ["流量", "水位", "库容", "入库流量", "出库流量"]
                if not any(var in str(value) for var in valid_variables):
                    result["is_valid"] = False
                    result["error_message"] = "目标变量格式不正确"
                    result["suggestion"] = "请指定预报的目标变量：流量、水位、库容、入库流量、出库流量等"
                    
            elif param_name == "start_time":
                # 时间格式验证
                if isinstance(value, str):
                    # 尝试解析时间格式
                    time_patterns = [
                        r'(\d{4})[-/年](\d{1,2})[-/月](\d{1,2})日?\s*(\d{1,2})[时:点](\d{1,2})?分?',
                        r'(\d{4})-(\d{1,2})-(\d{1,2})\s+(\d{1,2}):(\d{1,2})',
                        r'(\d{1,2})月(\d{1,2})日\s*(\d{1,2})[时:点]',
                        r'明天|后天|今天'
                    ]
                    
                    is_valid_format = False
                    for pattern in time_patterns:
                        if re.search(pattern, value):
                            is_valid_format = True
                            break
                    
                    if not is_valid_format:
                        result["is_valid"] = False
                        result["error_message"] = "时间格式不正确"
                        result["suggestion"] = "请使用标准时间格式，如：2024-01-15 08:00、明天上午8点、1月15日8时等"
                        
            elif param_name == "forecast_duration":
                # 预报时长验证
                if not isinstance(value, (int, float)) or value <= 0 or value > 168:  # 最大7天
                    result["is_valid"] = False
                    result["error_message"] = "预报时长格式不正确"
                    result["suggestion"] = "请提供有效的预报时长（1-168小时），如：24小时、48小时、72小时等"
                    
            elif param_name == "rainfall_forecast_period":
                # 降雨预见期验证
                if not isinstance(value, (int, float)) or value <= 0 or value > 72:  # 最大3天
                    result["is_valid"] = False
                    result["error_message"] = "降雨预见期格式不正确"
                    result["suggestion"] = "请提供有效的降雨预见期（1-72小时），如：6小时、12小时、24小时等"
                    
        except Exception as e:
            logger.error(f"参数验证出错: {e}")
            result["is_valid"] = False
            result["error_message"] = f"参数验证过程中出现错误: {str(e)}"
            
        return result
    
    def _check_completion(self) -> bool:
        """检查是否所有必需参数都已收集"""
        return all(param["value"] is not None for param in self.required_parameters.values())
        
    def _get_missing_parameters(self) -> List[str]:
        """获取缺失的参数列表"""
        return [key for key, param in self.required_parameters.items() if param["value"] is None]
    
    def _detect_confirmation_intent(self, user_input: str) -> bool:
        """检测用户输入是否为确认意图"""
        confirmation_patterns = [
            r'确认|确定|对的?|是的?|没错|正确|好的?|可以|行|同意',
            r'yes|ok|correct|right|confirm',
            r'就这样|就是这样|没问题|开始预报|开始吧'
        ]
        
        rejection_patterns = [
            r'不对|不是|错了|修改|更改|重新|不正确',
            r'no|wrong|incorrect|change|modify'
        ]
        
        user_input_lower = user_input.lower().strip()
        
        # 检查确认模式
        for pattern in confirmation_patterns:
            if re.search(pattern, user_input_lower):
                return True
                
        # 检查拒绝模式
        for pattern in rejection_patterns:
            if re.search(pattern, user_input_lower):
                return False
                
        # 如果输入很短且包含肯定词汇，认为是确认
        if len(user_input_lower) <= 5 and any(word in user_input_lower for word in ['是', '对', '好', 'ok', 'yes']):
            return True
            
        return False
    
    def _validate_all_parameters(self) -> Dict[str, Any]:
        """验证所有已收集的参数
        
        Returns:
            Dict包含:
            - all_valid: 是否所有参数都有效
            - validation_results: 每个参数的验证结果
            - error_summary: 错误摘要
        """
        validation_results = {}
        all_valid = True
        error_messages = []
        
        for param_name, param_info in self.required_parameters.items():
            if param_info["value"] is not None:
                validation_result = self._validate_parameter_format(param_name, param_info["value"])
                validation_results[param_name] = validation_result
                
                if not validation_result["is_valid"]:
                    all_valid = False
                    error_messages.append(f"{param_info['description']}: {validation_result['error_message']}")
                    
        return {
            "all_valid": all_valid,
            "validation_results": validation_results,
            "error_summary": error_messages
        }
        
    def process_user_input(self, user_input: str) -> Dict[str, Any]:
        """处理用户输入并返回响应
        
        Returns:
            Dict包含:
            - response: AI回复内容
            - status: 状态 (collecting/completed/error)
            - parameters: 当前收集到的参数
            - missing_parameters: 缺失的参数
        """
        logger.info(f"开始处理用户输入: {user_input}")
        
        try:
            # 处理等待确认状态
            if self.conversation_state == "awaiting_confirmation":
                if self._detect_confirmation_intent(user_input):
                    # 用户确认，完成收集
                    self.conversation_state = "completed"
                    response = "✅ 确认完成！所有参数已收集并验证通过。您可以使用get_final_parameters_json()方法获取最终的JSON配置。"
                    
                    # 添加到对话历史
                    self.chat_history.append(HumanMessage(content=user_input))
                    self.chat_history.append(AIMessage(content=response))
                    
                    return {
                        "response": response,
                        "status": self.conversation_state,
                        "parameters": {k: v["value"] for k, v in self.required_parameters.items()},
                        "missing_parameters": [],
                        "extracted_this_turn": {},
                        "validation_errors": []
                    }
                else:
                    # 用户不确认，重新收集
                    self.conversation_state = "collecting"
                    self.pending_confirmation = False
                    response = "好的，让我们重新确认参数。请告诉我需要修改哪些参数，或者重新提供完整的预报需求。"
            
            # 处理收集和验证状态
            elif self.conversation_state in ["collecting", "validating"]:
                # 提取参数
                logger.debug("开始提取参数")
                extracted_params = self._extract_parameters_from_text(user_input)
                logger.debug(f"提取到的参数: {extracted_params}")
                
                self._update_parameters(extracted_params)
                logger.debug(f"更新后的参数状态: {self.required_parameters}")
                
                # 检查是否完成收集
                if self._check_completion():
                    # 验证所有参数
                    validation_result = self._validate_all_parameters()
                    
                    if validation_result["all_valid"]:
                        # 所有参数有效，请求用户确认
                        self.conversation_state = "awaiting_confirmation"
                        self.pending_confirmation = True
                        
                        # 生成参数摘要
                        summary = "\n\n📋 **参数摘要:**\n"
                        for key, param in self.required_parameters.items():
                            if param["value"] is not None:
                                summary += f"- {param['description']}: {param['value']}\n"
                        
                        response = f"太好了！我已经收集到了所有必需的参数。{summary}\n\n请确认以上参数是否正确？如果正确，请回复'确认'或'是的'；如果需要修改，请告诉我具体要修改什么。"
                        
                    else:
                        # 存在验证错误
                        self.conversation_state = "validating"
                        self.validation_errors = validation_result["error_summary"]
                        
                        error_msg = "\n\n❌ **参数格式问题:**\n"
                        for i, error in enumerate(validation_result["error_summary"], 1):
                            error_msg += f"{i}. {error}\n"
                        
                        # 提供修正建议
                        suggestions = "\n\n💡 **修正建议:**\n"
                        for param_name, validation_info in validation_result["validation_results"].items():
                            if not validation_info["is_valid"] and validation_info["suggestion"]:
                                suggestions += f"- {validation_info['suggestion']}\n"
                        
                        response = f"检测到一些参数格式问题，请根据以下提示进行修正：{error_msg}{suggestions}"
                        
                else:
                    # 继续收集缺失参数
                    # 添加到对话历史
                    logger.debug("添加用户消息到历史")
                    self.chat_history.append(HumanMessage(content=user_input))
                    
                    # 创建提示词
                    logger.debug("创建系统提示词")
                    system_prompt = self._create_system_prompt()
                    logger.debug(f"系统提示词长度: {len(system_prompt)}")
                    
                    # 构建对话历史 - 使用正确的消息格式
                    from langchain_core.messages import SystemMessage, HumanMessage as LCHumanMessage, AIMessage as LCAIMessage
                    
                    messages = []
                    messages.append(SystemMessage(content=system_prompt))
                    logger.debug(f"添加系统消息，长度: {len(system_prompt)}")
                    
                    # 添加历史对话（如果有）
                    try:
                        logger.debug("处理聊天历史")
                        logger.debug(f"聊天历史消息数量: {len(self.chat_history)}")
                        
                        if len(self.chat_history) > 1:  # 跳过刚添加的当前消息
                            # 只保留最近4条消息（2轮对话），并确保安全访问
                            recent_messages = self.chat_history[-4:] if len(self.chat_history) >= 4 else self.chat_history[:-1]
                            logger.debug(f"处理最近的 {len(recent_messages)} 条消息")
                            
                            for i, msg in enumerate(recent_messages):
                                try:
                                    logger.debug(f"处理第 {i+1} 条历史消息: {type(msg)}")
                                    if isinstance(msg, HumanMessage) and hasattr(msg, 'content') and msg.content != user_input:
                                        messages.append(LCHumanMessage(content=str(msg.content)))
                                        logger.debug(f"添加历史用户消息: {msg.content[:50]}...")
                                    elif isinstance(msg, AIMessage) and hasattr(msg, 'content'):
                                        messages.append(LCAIMessage(content=str(msg.content)))
                                        logger.debug(f"添加历史AI消息: {msg.content[:50]}...")
                                except (AttributeError, IndexError) as e:
                                    logger.error(f"处理第 {i+1} 条消息时出错: {e}")
                                    logger.error(f"消息类型: {type(msg)}, 消息内容: {msg}")
                                    continue
                    except Exception as e:
                        logger.error(f"处理聊天历史时出错: {e}")
                        logger.error(f"错误详情: {traceback.format_exc()}")
                        # 如果历史处理失败，只使用系统提示和当前消息
                    
                    # 添加当前用户输入作为最后一条消息
                    messages.append(LCHumanMessage(content=user_input))
                    logger.debug(f"最终消息数量: {len(messages)}")
                    
                    # 直接调用LLM，不使用ChatPromptTemplate
                    try:
                        logger.debug("直接调用LLM")
                        logger.debug(f"消息列表: {[type(msg).__name__ for msg in messages]}")
                        
                        llm_response = self.llm.invoke(messages)
                        logger.debug(f"LLM响应类型: {type(llm_response)}")
                        
                        response = llm_response.content if hasattr(llm_response, 'content') else str(llm_response)
                        logger.debug(f"AI回复长度: {len(response)}")
                        
                        # 添加AI回复到历史
                        self.chat_history.append(AIMessage(content=response))
                        logger.debug("AI回复已添加到历史")
                        
                    except Exception as e:
                        logger.error(f"LLM调用出错: {e}")
                        logger.error(f"错误详情: {traceback.format_exc()}")
                        logger.error(f"消息结构: {[type(msg).__name__ + ': ' + str(msg.content)[:50] + '...' for msg in messages]}")
                        
                        # 检查是否是连接错误
                        if "ConnectError" in str(e) or "10061" in str(e) or "拒绝" in str(e):
                            response = "无法连接到Ollama服务。请确保：\n1. Ollama已安装并正在运行\n2. 服务运行在 http://localhost:11434\n3. 模型 'qwen:latest' 已下载\n\n请启动Ollama服务后重试。"
                        else:
                            response = "抱歉，我在处理您的请求时遇到了问题。请重新描述您的洪水预报需求。"
            
            # 添加到对话历史（如果还没有添加）
            if self.conversation_state != "collecting" or not self._check_completion():
                self.chat_history.append(HumanMessage(content=user_input))
                self.chat_history.append(AIMessage(content=response))
            
            return {
                "response": response,
                "status": self.conversation_state,
                "parameters": {k: v["value"] for k, v in self.required_parameters.items()},
                "missing_parameters": self._get_missing_parameters(),
                "extracted_this_turn": extracted_params if 'extracted_params' in locals() else {},
                "validation_errors": getattr(self, 'validation_errors', [])
            }
            
        except Exception as e:
            logger.error(f"process_user_input方法出现严重错误: {e}")
            logger.error(f"错误详情: {traceback.format_exc()}")
            logger.error(f"用户输入: {user_input}")
            logger.error(f"当前参数状态: {self.required_parameters}")
            
            self.conversation_state = "error"
            return {
                "response": f"处理过程中出现错误：{str(e)}",
                "status": "error",
                "parameters": {k: v["value"] for k, v in self.required_parameters.items()},
                "missing_parameters": self._get_missing_parameters(),
                "extracted_this_turn": {},
                "validation_errors": []
            }
            
    def get_final_parameters_json(self) -> str:
        """获取最终的参数JSON字符串"""
        if self.conversation_state != "completed":
            raise ValueError("参数收集尚未完成")
            
        final_params = {
            "forecast_request": {
                "reservoir_name": self.required_parameters["reservoir_name"]["value"],
                "forecast_model": self.required_parameters["forecast_model"]["value"],
                "start_time": self.required_parameters["start_time"]["value"],
                "forecast_duration_hours": self.required_parameters["forecast_duration"]["value"],
                "rainfall_forecast_period_hours": self.required_parameters["rainfall_forecast_period"]["value"],
                "target_variable": self.required_parameters["target_variable"]["value"],
                "created_at": datetime.now().isoformat(),
                "request_id": f"flood_forecast_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
            }
        }
        
        return json.dumps(final_params, ensure_ascii=False, indent=2)
        
    def reset(self):
        """重置收集器状态"""
        for param in self.required_parameters.values():
            param["value"] = None
        self.chat_history.clear()
        self.conversation_state = "collecting"
        self.validation_errors = []
        self.pending_confirmation = False
        logger.info("参数收集器状态已重置")